<!DOCTYPE html>
<html>
<head>
    <title>Electromagnetic Field Diagram</title>
    <style>
        canvas {
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas id="physicsCanvas" width="600" height="400"></canvas>
    <script>
        const canvas = document.getElementById('physicsCanvas');
        const ctx = canvas.getContext('2d');

        // Style settings
        ctx.font = 'italic 20px "Times New Roman"';
        ctx.strokeStyle = '#333';
        ctx.fillStyle = '#333';
        ctx.lineWidth = 1.2;
        
        // Translate origin to a convenient location
        ctx.translate(80, 220);

        // --- Define Geometry Parameters ---
        const b_val = 80;
        const d_val = 120;
        const a_val = 100;
        const l_val = 120;
        const topY = -140;

        // 1. Draw X-axis
        ctx.beginPath();
        ctx.moveTo(-40, 0);
        ctx.lineTo(420, 0);
        ctx.stroke();
        // Arrowhead for x-axis
        ctx.beginPath();
        ctx.moveTo(420, 0);
        ctx.lineTo(412, -4);
        ctx.moveTo(420, 0);
        ctx.lineTo(412, 4);
        ctx.stroke();
        // Axis labels
        ctx.fillText('O', -20, 18);
        ctx.fillText('x', 430, 8);
        // Ticks on axis
        ctx.beginPath();
        ctx.moveTo(0, -5); ctx.lineTo(0, 5); // at O
        ctx.moveTo(b_val, -5); ctx.lineTo(b_val, 5); // at b
        ctx.stroke();

        // 2. Draw Wires with currents
        const wireTopExtend = topY - 20;
        const wireBottomExtend = 20;
        const arrowY = topY - 15;
        const arrowLength = 20;

        // Wire 1 at x=0
        ctx.beginPath();
        ctx.moveTo(0, topY);
        ctx.lineTo(0, 0);
        ctx.stroke();
        ctx.beginPath();
        ctx.setLineDash([4, 4]);
        ctx.moveTo(0, topY); ctx.lineTo(0, wireTopExtend);
        ctx.moveTo(0, 0); ctx.lineTo(0, wireBottomExtend);
        ctx.stroke();
        ctx.setLineDash([]);
        // Current I1 (downward)
        ctx.beginPath();
        ctx.moveTo(0, arrowY); ctx.lineTo(0, arrowY + arrowLength);
        ctx.stroke();
        ctx.beginPath();
        ctx.moveTo(0, arrowY + arrowLength); ctx.lineTo(-4, arrowY + arrowLength - 6); ctx.lineTo(4, arrowY + arrowLength - 6);
        ctx.closePath();
        ctx.fill();
        ctx.fillText('I', -25, arrowY + 15);

        // Wire 2 at x=b
        ctx.beginPath();
        ctx.moveTo(b_val, topY);
        ctx.lineTo(b_val, 0);
        ctx.stroke();
        ctx.beginPath();
        ctx.setLineDash([4, 4]);
        ctx.moveTo(b_val, topY); ctx.lineTo(b_val, wireTopExtend);
        ctx.moveTo(b_val, 0); ctx.lineTo(b_val, wireBottomExtend);
        ctx.stroke();
        ctx.setLineDash([]);
        // Current I2 (upward)
        ctx.beginPath();
        ctx.moveTo(b_val, arrowY + arrowLength); ctx.lineTo(b_val, arrowY);
        ctx.stroke();
        ctx.beginPath();
        ctx.moveTo(b_val, arrowY); ctx.lineTo(b_val - 4, arrowY + 6); ctx.lineTo(b_val + 4, arrowY + 6);
        ctx.closePath();
        ctx.fill();
        ctx.fillText('I', b_val + 10, arrowY + 15);

        // 3. Draw the rectangular loop
        const loopX = b_val + d_val;
        ctx.beginPath();
        ctx.rect(loopX, topY, a_val, l_val);
        ctx.stroke();
        ctx.fillText('l', loopX + a_val + 5, topY + l_val / 2 + 5);

        // 4. Draw infinitesimal strip
        const stripX = loopX + 35;
        const dxWidth = 12;
        ctx.beginPath();
        ctx.rect(stripX, topY, dxWidth, l_val);
        ctx.stroke();
        // Shading for the strip
        ctx.save();
        ctx.beginPath();
        ctx.rect(stripX, topY, dxWidth, l_val);
        ctx.clip();
        ctx.lineWidth = 0.8;
        for (let i = -10; i < l_val + 10; i += 5) {
            ctx.beginPath();
            ctx.moveTo(stripX, topY + i);
            ctx.lineTo(stripX + dxWidth, topY + i - dxWidth);
            ctx.stroke();
        }
        ctx.restore();

        // 5. Draw Dimensions and Labels
        // Horizontal line for 'b'
        ctx.beginPath();
        ctx.moveTo(0, topY);
        ctx.lineTo(b_val, topY);
        ctx.stroke();
        ctx.fillText('b', b_val + 5, topY + 5);

        // Horizontal line from wire 2 to the loop
        ctx.beginPath();
        ctx.moveTo(b_val, topY);
        ctx.lineTo(loopX, topY);
        ctx.stroke();
        
        // Dimension for 'dx'
        const dx_dim_y = topY - 10;
        ctx.beginPath();
        ctx.moveTo(stripX, dx_dim_y); ctx.lineTo(stripX + dxWidth, dx_dim_y);
        ctx.moveTo(stripX, dx_dim_y-3); ctx.lineTo(stripX, dx_dim_y+3);
        ctx.moveTo(stripX + dxWidth, dx_dim_y-3); ctx.lineTo(stripX + dxWidth, dx_dim_y+3);
        ctx.stroke();
        ctx.fillText('dx', stripX + dxWidth/2 - 10, dx_dim_y - 8);

        // Position 'x' on the axis
        const x_pos = stripX + dxWidth / 2;
        ctx.beginPath();
        ctx.moveTo(x_pos, -5); ctx.lineTo(x_pos, 5);
        ctx.stroke();
        ctx.fillText('x', x_pos - 5, 20);

        // Dimension lines for 'd' and 'a'
        const dim_y = 40;
        const tick_h = 4;
        const arrow_size = 6;
        
        function drawDimArrow(x_start, x_end, y, label) {
            ctx.beginPath();
            ctx.moveTo(x_start, y - tick_h); ctx.lineTo(x_start, y + tick_h);
            ctx.moveTo(x_end, y - tick_h); ctx.lineTo(x_end, y + tick_h);
            ctx.moveTo(x_start, y); ctx.lineTo(x_end, y);
            ctx.stroke();
            
            ctx.beginPath();
            ctx.moveTo(x_start, y); ctx.lineTo(x_start + arrow_size, y - arrow_size / 2);
            ctx.moveTo(x_start, y); ctx.lineTo(x_start + arrow_size, y + arrow_size / 2);
            ctx.moveTo(x_end, y); ctx.lineTo(x_end - arrow_size, y - arrow_size / 2);
            ctx.moveTo(x_end, y); ctx.lineTo(x_end - arrow_size, y + arrow_size / 2);
            ctx.stroke();
            ctx.fillText(label, (x_start + x_end) / 2 - 5, y - 8);
        }

        drawDimArrow(b_val, b_val + d_val, dim_y, 'd');
        drawDimArrow(b_val + d_val, b_val + d_val + a_val, dim_y, 'a');
        
        // Redraw the shared tick mark for 'd' and 'a' to make it a single solid line
        ctx.beginPath();
        ctx.moveTo(b_val + d_val, dim_y - tick_h);
        ctx.lineTo(b_val + d_val, dim_y + tick_h);
        ctx.stroke();

        // Title text
        ctx.font = '24px "Microsoft YaHei", sans-serif';
        ctx.fillText('题 7 图', 150, 120);

    </script>
</body>
</html>